package com.canal.admin.handler;

import com.canal.admin.dao.*;
import com.canal.admin.entity.canal.ZcolChannelItem;
import com.canal.admin.entity.data.ZcolBusRecord;
import com.canal.admin.entity.data.ZcolRtReg;
import com.canal.admin.entity.data.ZcolStData;
import com.canal.admin.transfer.req.data.RtConvertConditions;
import com.canal.admin.transfer.resp.rt.CanalUvIncome;
import com.canal.admin.transfer.resp.rt.RtConvertResp;
import com.canal.admin.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yangbo
 * @date 2020-07-16 10:45
 */
@Component
@Slf4j
public class RtToHistoryDateHandler {

    @Autowired
    private ZcolRtDataMapper zcolRtDataMapper;

    @Autowired
    private ZcolRtRegMapper zcolRtRegMapper;

    @Autowired
    private ZcolLoginRecordMapper zcolLoginRecordMapper;

    @Autowired
    private ZcolStDataMapper zcolStDataMapper;

    @Autowired
    private ZcolChannelItemMapper zcolChannelItemMapper;

    @Autowired
    private ZcolBusRecordMapper zcolBusRecordMapper;

    /**
     * 实时数据转为历史数据
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void rtToHistory() {
        log.info("{}: =========== 数据结转开始 ===========",System.currentTimeMillis());
        RtConvertConditions conditions = new RtConvertConditions();
        conditions.setDiffDate(1);
        List<ZcolStData> stDataList = getConvertDate(conditions);
        if(stDataList != null && !stDataList.isEmpty()) {
            zcolStDataMapper.saveAll(stDataList);
        }
        log.info("{}: =========== 数据结转结束 ===========",System.currentTimeMillis());
    }

    /**
     * 实时数据转渠道历史数据
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void rtToCanalHistory() {
        //得到所有的渠道id
        List<ZcolChannelItem> channelItemList = zcolChannelItemMapper.findAll();
        for (ZcolChannelItem item : channelItemList) {
            RtConvertConditions conditions = new RtConvertConditions();
            conditions.setChannelId(item.getZcolChannel().getId().longValue());
            conditions.setChannelItemId(item.getId());
            conditions.setDiffDate(1);
            if(item.getStopTime() == null) {
                //按正常扣量即可
                conditions.setStartTime(DateUtil.getTime(item.getInputStart()));
                conditions.setEndTime(DateUtil.getTime(item.getInputEnd()));
                List<ZcolStData> stDataList = getConvertDate(conditions);
                List<ZcolBusRecord> busRecordList = convertToBusRecord(stDataList,item.getDiscountRate());
                zcolBusRecordMapper.saveAllBusRecord(busRecordList);
            } else {
                LocalDate stopDay = item.getStopTime().toInstant().atOffset(ZoneOffset.of("+8")).toLocalDate();
                LocalDate yesterday = LocalDateTime.now().minusDays(1).toLocalDate();
                //说明是昨天暂停的
                if(yesterday.toEpochDay() - stopDay.toEpochDay() == 0) {
                    long stopTime = item.getStopTime().getTime();
                    long startTime = item.getInputStart().getTime();
                    long endTime = item.getInputEnd().getTime();
                    if(stopTime > startTime) {
                        conditions.setStartTime(DateUtil.getTime(item.getInputStart()));
                        if (stopTime < endTime) {
                            //进量时间段为startTime stopTime
                            conditions.setEndTime(DateUtil.getTime(item.getStopTime()));
                        } else {
                            //进量时间段为startTime endTime
                            conditions.setEndTime(DateUtil.getTime(item.getInputEnd()));
                        }
                    }
                    List<ZcolStData> stDataList = getConvertDate(conditions);
                    List<ZcolBusRecord> busRecordList = convertToBusRecord(stDataList,item.getDiscountRate());
                    zcolBusRecordMapper.saveAllBusRecord(busRecordList);
                }
            }
        }
    }

    /**
     * 转换
     * @param stDataList
     * @return
     */
    private List<ZcolBusRecord> convertToBusRecord(List<ZcolStData> stDataList,int disCountRate) {
        List<ZcolBusRecord> busRecordList = new ArrayList<>();
        for (ZcolStData stData : stDataList) {
            ZcolBusRecord busRecord = new ZcolBusRecord();
            busRecord.setChannelItemId(stData.getChannelItemId().longValue());
            BigDecimal rate = new BigDecimal(disCountRate).divide(new BigDecimal(100),2,RoundingMode.HALF_DOWN);
            Integer pv = new BigDecimal(stData.getPv()).multiply(rate).intValue();
            Integer uv = new BigDecimal(stData.getUv()).multiply(rate).intValue();
            Integer regCount = new BigDecimal(stData.getRegCount()).multiply(rate).intValue();
            busRecord.setPv(pv);
            busRecord.setUv(uv);
            busRecord.setRegCount(regCount);
            busRecord.setRecordDate(stData.getRecordDate());
            busRecordList.add(busRecord);
        }
        return busRecordList;
    }

    /**
     * 得到实时转化数据列表
     * @param conditions
     * @return
     */
    private List<ZcolStData> getConvertDate(RtConvertConditions conditions) {
        //表示上一天的数据，因为一般是在00:00:00进行结转
        List<RtConvertResp> convertRespList = zcolRtDataMapper.rtConvertList(conditions);
        List<RtConvertResp> resultList = new ArrayList<>(convertRespList.size() + 1);
        List<CanalUvIncome> uvIncomeList = new ArrayList<>();
        if(!convertRespList.isEmpty()) {
            List<String> canals = convertRespList.stream().map(RtConvertResp::getItemName)
                    .distinct().collect(Collectors.toList());
            uvIncomeList = zcolRtDataMapper.canalIncome(canals,0);
        }
        for (RtConvertResp convert : convertRespList) {
            BigDecimal uvCostAmount = convert.getUvPrice().multiply(new BigDecimal(convert.getUv()))
                    .setScale(2, RoundingMode.HALF_DOWN);
            List<ZcolRtReg> zcolRtRegList = zcolRtRegMapper.rtRegByChannel(convert.getCiid(),conditions.getDiffDate());
            int regCount = zcolRtRegList.size();
            BigDecimal regCostAmount = convert.getRegPrice().multiply(new BigDecimal(regCount));
            List<String> phones = zcolRtRegList.stream().map(ZcolRtReg::getPhone).collect(Collectors.toList());
            int loginCount = 0;
            if(!phones.isEmpty()) {
                loginCount = zcolLoginRecordMapper.loginCount(convert.getCiid(),phones);
            }
            convert.setUvCostAmount(uvCostAmount);
            convert.setRegCount(regCount);
            convert.setRegCostAmount(regCostAmount);
            convert.setLoginCount(loginCount);
            //获取商家信息并计算毛利
            CanalUvIncome canalUvIncome = getItem(uvIncomeList,convert.getItemName());
            if(canalUvIncome != null) {
                convert.setCanalUv(canalUvIncome.getCanalUv());
                convert.setIncomeAmount(canalUvIncome.getIncomeAmount());
            } else {
                convert.setCanalUv(0);
                convert.setIncomeAmount(BigDecimal.ZERO);
            }
            resultList.add(convert);
        }
        List<ZcolStData> stDataList = new ArrayList<>(resultList.size());
        for (RtConvertResp convert : resultList) {
            ZcolStData stData = new ZcolStData();
            stData.setChannelItemId(convert.getCiid());
            stData.setRecordDate(convert.getRecordDate());
            stData.setPv(convert.getPv());
            stData.setUv(convert.getUv());
            stData.setUvPrice(convert.getUvPrice());
            stData.setUvCostSum(convert.getUvCostAmount());
            stData.setRegCount(convert.getRegCount());
            stData.setRegPrice(convert.getRegPrice());
            stData.setRegCost(convert.getRegCostAmount());
            stData.setLoginCount(convert.getLoginCount());
            stData.setAppUv(convert.getCanalUv());
            stData.setUvIncome(convert.getIncomeAmount());
            stDataList.add(stData);
        }
        return stDataList;
    }

    /**
     * 得到匹配的商家信息
     * @param uvIncomeList
     * @param itemName
     * @return
     */
    private CanalUvIncome getItem(List<CanalUvIncome> uvIncomeList,String itemName) {
        List<CanalUvIncome> items = uvIncomeList.stream().filter(item -> itemName.equals(item.getCanal()))
                .collect(Collectors.toList());
        if(items.isEmpty()) {
            return null;
        }
        return items.get(0);
    }
}
